package com.khstudio.filebrowser.duallist;

import java.util.ArrayList;

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.khstudio.filebrowser.R;
import com.khstudio.filebrowser.bitmapcache.KhBitmapCache;
import com.khstudio.filebrowser.bitmapcache.KhBitmapCacheParam;
import com.khstudio.filebrowser.duallist.KhFileBrowserItem.TYPE;
import com.khstudio.filebrowser.util.KhBitmapFactory;
import com.khstudio.filebrowser.util.KhLog;

public class KhFileBrowserAdapter extends ArrayAdapter<KhFileBrowserItem> {
    private static final int ICON_UNKNOWN            = R.drawable.kh_duallist_ic_unknown_file;
    private static final int ICON_UP                 = R.drawable.kh_duallist_ic_folder;
    private static final int ICON_SDCARD             = R.drawable.kh_duallist_ic_folder;
    private static final int ICON_EXTSDCARD          = R.drawable.kh_duallist_ic_folder;
    private static final int ICON_FOLDER             = R.drawable.kh_duallist_ic_folder;
    private static final int ICON_SUB_VIDEO          = R.drawable.kh_duallist_ic_sub_video;
    private static final int ICON_SUB_IMAGE          = R.drawable.kh_duallist_ic_sub_image;
    private static final int ICON_SUB_SELECT_ENABLE  = R.drawable.kh_duallist_ic_select_true;
    private static final int ICON_SUB_SELECT_DISABLE = R.drawable.kh_duallist_ic_select_false;

    public static enum SELECT {
        DISABLE,
        ENABLE
    };

    private final LayoutInflater        mInflater;
    private final KhBitmapCache         mBitmapCache;

    private int     mMainWidth;
    private int     mMainHeight;
    private int     mSubWidth;
    private int     mSubHeight;

    private SELECT  mSelect;
    private int     mArrowVisible;

    public void setSelectMode(SELECT s) {
        if(mSelect != s) {
            mSelect = s;
            notifyDataSetInvalidated();
        }
    }

    public void setArrowVisible(int v) {
        if(mArrowVisible != v) {
            mArrowVisible = v;
            notifyDataSetInvalidated();
        }
    }

    public SELECT getSelectMode() {
        return mSelect;
    }

    public int doSelect(KhFileBrowserItem item, View v) {
        if(item.getSelect()) {
            item.setSelect(false);
            ViewWrapper viewWrapper = (ViewWrapper) v.getTag();
            viewWrapper.getIcon().setSubIconId(ICON_SUB_SELECT_DISABLE);
            return -1;
        } else {
            item.setSelect(true);
            ViewWrapper viewWrapper = (ViewWrapper) v.getTag();
            viewWrapper.getIcon().setSubIconId(ICON_SUB_SELECT_ENABLE);
            return 1;
        }
    }

    public KhFileBrowserAdapter(Context context, ArrayList<KhFileBrowserItem> objects) {
        super(context, 0, objects);

        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        
        mSelect = SELECT.DISABLE;
        mArrowVisible = View.VISIBLE;
        
        Bitmap bitmap = KhBitmapFactory.decodeResource(context.getResources(), ICON_UNKNOWN);
        mMainWidth = bitmap.getWidth();
        mMainHeight = bitmap.getHeight();
        bitmap.recycle();

        bitmap = KhBitmapFactory.decodeResource(context.getResources(), ICON_SUB_VIDEO);
        mSubWidth = bitmap.getWidth();
        mSubHeight = bitmap.getHeight();
        bitmap.recycle();

        final int largeMemClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getLargeMemoryClass();
        final int largeDiskSize = 1024 * 1024 * largeMemClass / 8;
        final int largeCacheSize = 1024 * 1024 * largeMemClass / 32;

        mBitmapCache = new KhBitmapCache(context, "KhFileListView", largeCacheSize, largeDiskSize) {
            @Override
            public Bitmap onLoadBitmap(String filename) {
                TYPE fileType = KhFileBrowserItem.getType(filename);
                Bitmap bm = null;

                if(fileType == TYPE.VIDEO) {
                    Bitmap frame = null;
                    try {
                        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
                        retriever.setDataSource(filename);
                        frame = retriever.getFrameAtTime();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if(frame != null) {
                        bm = KhBitmapFactory.createBitmapOnRatio(frame, mMainWidth, mMainHeight);
                    } else {
                        KhLog.w("onLoadBitmap null path = " + filename);
                    }
                } else if(fileType == TYPE.IMAGE) {
                    bm = KhBitmapFactory.createBitmapOnRatioFast(filename, mMainWidth, mMainHeight);
                }

                return bm;
            }

            @Override
            public void onLoadDone(KhBitmapCacheParam<?> param) {
                Message msg = mAdapterHandler.obtainMessage();
                msg.obj = param;
                mAdapterHandler.sendMessage(msg);
            }
        };
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View        view = convertView;
        ViewWrapper viewWrapper;

        if(view == null) {
            view = mInflater.inflate(R.layout.kh_duallist_row_filebrowser, null);
            viewWrapper = new ViewWrapper(view);
            viewWrapper.getIcon().setSize(mMainWidth, mMainHeight, mSubWidth, mSubHeight);
            view.setTag(viewWrapper);
        } else {
            viewWrapper = (ViewWrapper)view.getTag();
        }

        final KhFileBrowserItem data = this.getItem(position);

        if(data != null) {
            viewWrapper.setPath(data.getPath());

            if(data.getType() == TYPE.UP) {
                _viewWrapper_UP(viewWrapper, data);
            } else if(data.getType() == TYPE.SDCARD) {
                _viewWrapper_SDCARD(viewWrapper, data);
            } else if(data.getType() == TYPE.EXTSDCARD) {
                _viewWrapper_EXTSDCARD(viewWrapper, data);
            } else if(data.getType() == TYPE.FOLDER) {
                _viewWrapper_FOLDER(viewWrapper, data);
            } else if(data.getType() == TYPE.VIDEO) {
                _viewWrapper_VIDEO(viewWrapper, data);
            } else if(data.getType() == TYPE.IMAGE) {
                _viewWrapper_IMAGE(viewWrapper, data);
            } else {
                _viewWrapper_UNKNOWN(viewWrapper, data);
            }
        }
        return view;
    }

    private void _viewWrapper_UP(ViewWrapper wrapper, KhFileBrowserItem item) {
        wrapper.getIcon().setMainIconId(ICON_UP);
        wrapper.getIcon().setSubIconId(KhSubImageView.None);
        wrapper.getName().setText(item.getName());
        wrapper.getArrow().setVisibility(View.GONE);
    }

    private void _viewWrapper_SDCARD(ViewWrapper wrapper, KhFileBrowserItem item) {
        wrapper.getIcon().setMainIconId(ICON_SDCARD);
        wrapper.getIcon().setSubIconId(KhSubImageView.None);
        wrapper.getName().setText(item.getName());
        wrapper.getArrow().setVisibility(View.GONE);
    }

    private void _viewWrapper_EXTSDCARD(ViewWrapper wrapper, KhFileBrowserItem item) {
        wrapper.getIcon().setMainIconId(ICON_EXTSDCARD);
        wrapper.getIcon().setSubIconId(KhSubImageView.None);
        wrapper.getName().setText(item.getName());
        wrapper.getArrow().setVisibility(View.GONE);
    }

    private void _viewWrapper_FOLDER(ViewWrapper wrapper, KhFileBrowserItem item) {
        wrapper.getIcon().setMainIconId(ICON_FOLDER);
        wrapper.getIcon().setSubIconId(KhSubImageView.None);
        wrapper.getName().setText(item.getName());
        wrapper.getArrow().setVisibility(View.GONE);
    }

    private void _viewWrapper_UNKNOWN(ViewWrapper wrapper, KhFileBrowserItem item) {
        wrapper.getIcon().setMainIconId(ICON_UNKNOWN);
        wrapper.getArrow().setVisibility(View.GONE);
        if(mSelect == SELECT.ENABLE && item.getSelect()) {
            wrapper.getIcon().setSubIconId(ICON_SUB_SELECT_ENABLE);
        } else if(mSelect == SELECT.ENABLE) {
            wrapper.getIcon().setSubIconId(ICON_SUB_SELECT_DISABLE);
        } else {
            wrapper.getIcon().setSubIconId(KhSubImageView.None);
        }
        wrapper.getName().setText(item.getName());
    }

    private void _viewWrapper_IMAGE(ViewWrapper wrapper, KhFileBrowserItem item) {
        Bitmap bm = mBitmapCache.load(new KhBitmapCacheParam<ViewWrapper>(item.getPath(), wrapper));
        if(bm == null)  wrapper.getIcon().setMainIconId(ICON_UNKNOWN);
        else            wrapper.getIcon().setMainIconBMP(bm);
        wrapper.getName().setText(item.getName());
        if(mSelect == SELECT.ENABLE && item.getSelect()) {
            wrapper.getArrow().setVisibility(View.GONE);
            wrapper.getIcon().setSubIconId(ICON_SUB_SELECT_ENABLE);
        } else if(mSelect == SELECT.ENABLE) {
            wrapper.getArrow().setVisibility(View.GONE);
            wrapper.getIcon().setSubIconId(ICON_SUB_SELECT_DISABLE);
        } else {
            wrapper.getArrow().setVisibility(mArrowVisible);
            wrapper.getIcon().setSubIconId(ICON_SUB_IMAGE);
        }
    }

    private void _viewWrapper_VIDEO(ViewWrapper wrapper, KhFileBrowserItem item) {
        Bitmap bm = mBitmapCache.load(new KhBitmapCacheParam<ViewWrapper>(item.getPath(), wrapper));
        if(bm == null)  wrapper.getIcon().setMainIconId(ICON_UNKNOWN);
        else            wrapper.getIcon().setMainIconBMP(bm);
        wrapper.getName().setText(item.getName());
        if(mSelect == SELECT.ENABLE && item.getSelect()) {
            wrapper.getArrow().setVisibility(View.GONE);
            wrapper.getIcon().setSubIconId(ICON_SUB_SELECT_ENABLE);
        } else if(mSelect == SELECT.ENABLE) {
            wrapper.getArrow().setVisibility(View.GONE);
            wrapper.getIcon().setSubIconId(ICON_SUB_SELECT_DISABLE);
        } else {
            wrapper.getArrow().setVisibility(mArrowVisible);
            wrapper.getIcon().setSubIconId(ICON_SUB_VIDEO);
        }
    }

    private final Handler mAdapterHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            KhBitmapCacheParam<?> param = (KhBitmapCacheParam<?>) msg.obj;

            ViewWrapper viewWrapper = (ViewWrapper)param.getParam();
            if(viewWrapper.getPath().equals(param.getPath())) {
                if(param.getBitmap() == null) {
                    KhFileBrowserItem item = null;
                    for(int i = 0; i < getCount(); i++) {
                        if(getItem(i).getPath().equals(param.getPath())) {
                            item = getItem(i);
                        }
                    }
                    if(item != null) {
                        item.setType(TYPE.UNKNOWN);
                        viewWrapper.getIcon().setMainIconId(ICON_UNKNOWN);
                        viewWrapper.getArrow().setVisibility(View.GONE);
                        if(mSelect == SELECT.ENABLE && item.getSelect()) {
                            viewWrapper.getIcon().setSubIconId(ICON_SUB_SELECT_ENABLE);
                        } else if(mSelect == SELECT.ENABLE) {
                            viewWrapper.getIcon().setSubIconId(ICON_SUB_SELECT_DISABLE);
                        } else {
                            viewWrapper.getIcon().setSubIconId(KhSubImageView.None);
                        }
                    }
                } else {
                    viewWrapper.getIcon().setMainIconBMP(param.getBitmap());
                }
            }
        }
    };

    private class ViewWrapper {
        private View                    mBase;

        private KhSubImageView          mIcon;
        private TextView                mName;
        private ImageView               mArrow;

        private String                  mPath;

        public ViewWrapper(View base) {
            this.mBase = base;

            this.mIcon = null;
            this.mName = null;
            this.mArrow = null;
            this.mPath = null;
        }

        public void setPath(String path) {
            mPath = path;
        }

        public KhSubImageView getIcon() {
            if(mIcon == null) {
                mIcon = (KhSubImageView)mBase.findViewById(R.id.kh_duallist_row_filebrowser_icon);
            }
            return mIcon;
        }

        public TextView getName() {
            if(mName == null) {
                mName = (TextView)mBase.findViewById(R.id.kh_duallist_row_filebrowser_name);
            }
            return mName;
        }

        public ImageView getArrow() {
            if(mArrow == null) {
                mArrow = (ImageView)mBase.findViewById(R.id.kh_duallist_row_filebrowser_arrow);
            }
            return mArrow;
        }

        public String getPath() {
            return mPath;
        }
     }
}
